import React, { useEffect, useRef, useState } from 'react'
import { loadScript } from '@/utils/loadScript'
import { NameValueLength } from '@/types/sun'
import { CDN_ECHARTS } from '@/lib/utils'
import Loading from '@/components/Loading'
interface PieProps {
  data: NameValueLength[]
  title: string
  title2?: string
  tag?: string
  height?: string
  sum?: boolean
  count?: boolean
  unit?: string
}

export default function Pie({
  data,
  title,
  title2,
  tag = 'Count',
  height = '500px',
  // 默认不显示总和
  // 如果 sum 为 true，则显示总和
  // 如果 count 为 true，则显示长度总和 相当于group by name count
  sum = false,
  count = false,
  unit = '人'
}: PieProps) {
  const chartRef = useRef<HTMLDivElement>(null)
  const [loading, setLoading] = useState(true)
  // 用于保存 chart 实例，避免多次初始化
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const chartInstance = useRef<any>(null)

  useEffect(() => {
    let isMounted = true
    setLoading(true)

    // 若无数据，直接结束 loading
    if (!data || !Array.isArray(data) || data.length === 0) {
      setLoading(false)
      if (chartInstance.current) {
        chartInstance.current.dispose()
        chartInstance.current = null
      }
      return
    }

    function renderChart() {
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      if (!(window as any).echarts || !chartRef.current) return
      // 销毁旧实例，防止重复初始化
      if (chartInstance.current) {
        chartInstance.current.dispose()
      }
      // 兼容 theme
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      chartInstance.current = (window as any).echarts.init(
        chartRef.current,
        undefined,
        {
          renderer: 'canvas'
        }
      )
      const chart = chartInstance.current
      const numberFormatter = new Intl.NumberFormat('en-US')

      let finalTitle = title
      if (sum) {
        const totalLength = data.reduce((acc, item) => acc + item.value, 0)
        finalTitle = `${title} (${totalLength.toLocaleString()})`
      } else {
        finalTitle = `${title} (${data.length})`
      }
      if (count) {
        const totalLength = data.reduce((acc, item) => acc + item.length!, 0)
        finalTitle = `${title} (${totalLength})`
      }
      if (title2) {
        const totalLength = data.reduce((acc, item) => acc + item.value, 0)
        finalTitle = `${finalTitle} - ${title2}: ${totalLength.toLocaleString()}`
      }

      let total = 0
      if (sum) {
        total = data.reduce((acc, item) => acc + item.value, 0)
      } else if (count) {
        total = data.reduce((acc, item) => acc + (item.length ?? 0), 0)
      } else {
        total = data.length
      }

      const option = {
        title: {
          text: finalTitle,
          left: 'left'
        },
        tooltip: {
          trigger: 'item',
          formatter: (params: {
            seriesName: string
            name: string
            value: number
            percent: number
            data: { length?: number; value?: number }
          }) => {
            const value = numberFormatter.format(params.value)
            const length =
              params.data.length !== undefined && params.data.length !== 0
                ? `${params.data.length} ${unit}`
                : ''
            let percent = 0
            if (sum) {
              percent = total ? (params.value / total) * 100 : 0
            } else if (count) {
              percent = total ? ((params.data.length ?? 0) / total) * 100 : 0
            } else {
              percent = total ? (1 / total) * 100 : 0
            }
            return `${
              params.name
            } ${length}<br/> ${tag}: ${value} (${percent.toFixed(2)}%)`
          }
        },
        series: [
          {
            name: 'Data',
            type: 'pie',
            data: data,
            roseType: 'area'
          }
        ]
      }
      chart.setOption(option)
      chart.resize()
      setLoading(false)
    }

    // 增加超时时间和重试次数
    function waitForEcharts(retry = 60) {
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      if ((window as any).echarts && chartRef.current && isMounted) {
        renderChart()
      } else if (retry > 0) {
        setTimeout(() => waitForEcharts(retry - 1), 300)
      } else {
        setLoading(false)
        // 提示用户加载失败
        if (chartRef.current) {
          chartRef.current.innerHTML =
            '<div style="color:red;text-align:center;padding:2em;">ECharts 加载超时，请检查网络或稍后重试。</div>'
        }
      }
    }

    loadScript(CDN_ECHARTS)
      .then(() => {
        waitForEcharts()
      })
      .catch((e) => {
        setLoading(false)
        // eslint-disable-next-line no-console
        console.error('ECharts 加载失败', e)
      })

    // 监听窗口大小变化，自动 resize
    function handleResize() {
      if (chartInstance.current) {
        chartInstance.current.resize()
      }
    }
    window.addEventListener('resize', handleResize)

    return () => {
      isMounted = false
      window.removeEventListener('resize', handleResize)
      if (chartInstance.current) {
        try {
          chartInstance.current.dispose()
        } catch (e) {
          // ignore dispose error
        }
        chartInstance.current = null
      }
    }
  }, [data, title, title2, sum, count, tag, unit, height])

  return (
    <div style={{ position: 'relative', minHeight: height, width: '100%' }}>
      {loading && <Loading />}
      <div
        ref={chartRef}
        style={{ minHeight: height, width: '100%', background: '#fff' }}
      />
    </div>
  )
}
